from django.db import transaction
from rest_framework import serializers

from goods.models import SKU, SKUSpecification


class SKUSpecificationSerialzier(serializers.ModelSerializer):
    """
        SKU规格表序列化器
    """
    spec_id = serializers.IntegerField()
    option_id = serializers.IntegerField()

    class Meta:
        model = SKUSpecification  # SKUSpecification中sku外键关联了SKU表
        fields = ("spec_id", 'option_id')


class SKUSerializer(serializers.ModelSerializer):
    spu = serializers.StringRelatedField(label='商品SPU名称')
    spu_id = serializers.IntegerField(label='商品SPU ID')
    category_id = serializers.IntegerField(label='三级分类id')
    category = serializers.StringRelatedField(label='三级分类名称')

    specs = SKUSpecificationSerialzier(many=True, write_only=True)

    class Meta:
        model = SKU
        # fields = '__all__'
        exclude = ('create_time', 'update_time', 'comments', 'default_image_url',)  # 排除掉的字段

    def create(self, validated_data):
        # 获取规格信息,并从validated_data数据中,删除规格信息数据
        specs_data = validated_data.pop('specs')
        with transaction.atomic():
            # 开启事务
            savepoint = transaction.savepoint()
            # 保存sku
            sku = SKU.objects.create(**validated_data)
            # 对规格信息进行遍历,来保存商品规格信息
            for spec_data in specs_data:
                SKUSpecification.objects.create(sku=sku, **spec_data)

            # 清除保存点
            transaction.savepoint_commit(savepoint)
            # 返回sku
            return sku

    def update(self, instance, validated_data):
        # 获取规格信息,并从validated_data数据中,删除规格信息数据
        specs_data = validated_data.pop('specs')

        # 方案一： 调用父类 ，去实现没有问题的数据更新
        super().update(instance, validated_data)

        # 对规格信息进行遍历,来保存商品规格信息
        for item in specs_data:
            SKUSpecification.objects.filter(sku=instance, spec_id=item['spec_id']).update(option_id=item['option_id'])

        return instance
